﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KinSocket;

namespace KinConquer.Sockets
{
    public class GameSocket : KinSocket.KinSocket
    {
        public GameSocket()
            : base(Variables.GamePort)
        {
            
        }

        public override int OnAccept(Connection con)
        {
            try
            {
                con.Identifier = Program.GameConID.NextVal;
                con.Encryption = new KinSocket.Encryption.GameEncryption(Encoding.ASCII.GetBytes(Constants.EncryptionKey));
                con.KeyExchange = new KinSocket.Encryption.ServerKeyExchange();
                con.ActionTimer.Elapsed += delegate { Program.OnTimer(con); };
                Program.GameConnections.Add(con.Identifier, con);
                con.Send(con.KeyExchange.Serialize);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return 1;
            }
            return 0;
        }

        public override int OnReceive(Connection con, byte[] Data)
        {
            UInt16 type = BitConverter.ToUInt16(Data, 2);
            if (!Packets.Delegates.IgnorePackets.Contains(type))
            {
                if (Packets.Delegates.PacketHandles.ContainsKey(type))
                {
                    con.ReceiveQueue.Enqueue(Data);
                }
                else
                    Console.WriteLine("Unhandled Packet: {0}\n{1}", type, KinSocket.PacketConstructor.Dump(Data));
                return 0;
            }
            return 1;
        }

        public override int OnDisconnect(Connection con, string Reason)
        {
            Console.WriteLine("Disconnect Invoked:\n  Socket: {0}\n  Reason: {1}", con.ConnSocket.RemoteEndPoint, Reason);
            if (Program.GameConnections.ContainsKey(con.Identifier))
            {
                Program.GameConnections.Remove(con.Identifier);
            }
            Entities.Hero h = Program.GetHero(con.Identifier);
            if (h != null)
            {
                
                Program.HeroPool.Remove(h.Identifier);
            }
            return 0;
        }

        public override int OnException(Exception ex)
        {
            Console.WriteLine(ex);
            return 0;
        }
    }
}
